#include "esp_wifi.h"
#include "netutils.h"
#include "zyutils.h"

#define LOGTAG "SZW:netutils"


/**
 * @brief IP地址格式转换: uint32_t -> string
 */
char* ip4_u32_to_str(uint32_t ip, char *buf) {
	static char str[16];
	if(!buf) { buf = str; }
    snprintf(buf, 16, "%d.%d.%d.%d", (ip)&0xFF, (ip>>8)&0xFF, (ip>>16)&0xFF, (ip>>24)&0xFF);
    return buf;
}

/**
 * @brief 打印网络接口信息
 */
void tcpip_if_dump_info(esp_netif_t* tcpip_if) {
	esp_netif_ip_info_t ip_info;
	esp_netif_dns_info_t dns;
    char ip[20], netmask[16], gateway[16];
    const char *hostname;
    esp_err_t err = ESP_OK;

    if(tcpip_if == TCPIP_ADAPTER_IF_STA) {
        printf("dump WiFi AP info:");

        wifi_ap_record_t ap_info;
        err = esp_wifi_sta_get_ap_info(&ap_info);
        if(!err) printf(
            "\tap.ssid=%s, ap.bssid=%s, ap.rssi=%d",
            ap_info.ssid,
            bytes_to_hexstr(ap_info.bssid, 0, 6, ":", ip),
            ap_info.rssi
        );
    }

    // 主机名
    err = esp_netif_get_hostname(tcpip_if, &hostname);
    if(!err && hostname) printf("\thostname=%s", hostname);

    // IP/子网掩码/网关
    err = esp_netif_get_ip_info(tcpip_if, &ip_info);
    if(!err) printf(
        "\tip=%s, netmask=%s, gateway=%s",
        ip4_u32_to_str(ip_info.ip.addr, ip),
        ip4_u32_to_str(ip_info.netmask.addr, netmask),
        ip4_u32_to_str(ip_info.gw.addr, gateway)
    );

    // DNS
    err = esp_netif_get_dns_info(tcpip_if, ESP_NETIF_DNS_MAIN, &dns);
    if(!err) printf("\tdns_main=%s", ip4_u32_to_str(dns.ip.u_addr.ip4.addr, ip));
    err = esp_netif_get_dns_info(tcpip_if, ESP_NETIF_DNS_BACKUP, &dns);
    if(!err) printf("\tdns_backup=%s", ip4_u32_to_str(dns.ip.u_addr.ip4.addr, ip));
    err = esp_netif_get_dns_info(tcpip_if, ESP_NETIF_DNS_FALLBACK, &dns);
    if(!err) printf("\tdns_fallback=%s", ip4_u32_to_str(dns.ip.u_addr.ip4.addr, ip));
}

void ip4_info_str_to_struct(Ip4InfoStr *info, esp_netif_ip_info_t* st) {
    st->ip.addr = esp_ip4addr_aton(info->ip);
    st->gw.addr = esp_ip4addr_aton(info->gateway);
    st->netmask.addr = esp_ip4addr_aton(info->netmask);
}

void ip4_info_struct_to_str(esp_netif_ip_info_t* st, Ip4InfoStr* info) {
    char buf[32];
    strncpy(info->ip, esp_ip4addr_ntoa(&st->ip, buf, 32), IP4ADDR_STRLEN_MAX);
    strncpy(info->gateway, esp_ip4addr_ntoa(&st->gw, buf, 32), IP4ADDR_STRLEN_MAX);
    strncpy(info->netmask, esp_ip4addr_ntoa(&st->netmask, buf, 32), IP4ADDR_STRLEN_MAX);
}

/*
typedef int (*FUNC_getIp)(int s, struct sockaddr *name, socklen_t *namelen);
static sockaddr_in get_ip4(int _skt, FUNC_getIp func) {
	struct sockaddr addr;
	socklen_t len;

	if(_skt < 0) { loge("Invalid socket handle: %d", _skt); goto error; }
	if(!func(_skt, &addr, &len)) { loge("Get IP failed: %s", strerror(errno)); goto error; }
	if(addr.sa_family != AF_INET) { loge("Invalid socket address family: %d", addr.sa_family); goto error; }
	return *((sockaddr_in*)&addr);

error:
	memset(&addr, 0, sizeof(addr));
	return *((sockaddr_in*)&addr);
}

sockaddr_in ip4_getlocal(int skt) { return get_ip4(skt, getsockname); }
sockaddr_in ip4_getpeer(int skt) { return get_ip4(skt, getpeername); }
*/
